import 'dart:io';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:grouped_list/grouped_list.dart';

import '../../../common/models/ai/index.dart';
import '../../../common/routers/routes.dart';
import '../../../common/style/color.dart';
import '../../../common/style/icon_font.dart';
import '../../../common/utils/log_util.dart';
import '../../../common/utils/o2_api_manager.dart';
import '../../../common/utils/o2_utils.dart';
import '../../../common/values/file_icon.dart';
import '../../../common/widgets/o2_elevated_button.dart';
import 'index.dart';
import 'widgets/msg_list.dart';
import 'widgets/speech_button.dart';

class AiPage extends GetView<AiController> {
  const AiPage({Key? key}) : super(key: key);

  static void open() {
    Get.toNamed(O2OARoutes.appAI);
  }

  // 主视图
  Widget _buildView(BuildContext context) {
    return Column(
      children: [
        Expanded(flex: 1, child: _contentView(context)),
        _bottomBarView(context),
        // const SizedBox(height: 10)
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return GetBuilder<AiController>(
      builder: (_) {
        return LayoutBuilder(builder: (context, constraints) {
          OLogger.d(
              'Layout =======> width ${constraints.maxWidth} height ${constraints.maxHeight}');
          controller.state.screenWidth = constraints.maxWidth;
          if (constraints.maxWidth > 600) {
            controller.state.isBigScreen = true;
            return _bigScreenView(context);
          } else {
            controller.state.isBigScreen = false;
            return _smallScreenView(context);
          }
        });
      },
    );
  }

  Widget _bigScreenView(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Obx(() =>
            Text(controller.state.title.isEmpty ? (controller.state.config.value?.appName ?? 'app_name_ai'.tr) : controller.state.title)),
      ),
      body: SafeArea(
          child: Container(
              color: Theme.of(context).scaffoldBackgroundColor,
              child: Row(
                children: [
                  _bigScreenLeftSide(context),
                  Expanded(child: _buildView(context))
                ],
              ))),
    );
  }

  Widget _bigScreenLeftSide(BuildContext context) {
    return Obx(() {
      final w = controller.state.screenWidth / 3;
      double width = 200;
      if (w > 300) {
        width = 300;
      } else if (w < 200) {
        width = 200;
      } else {
        width = w;
      }
      return Container(
          width: width,
          color: Theme.of(context).colorScheme.surface,
          child: Column(
            children: [
              Padding(
                  padding: const EdgeInsets.only(top: 10, bottom: 10),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Expanded(child: newClueButton(context)),
                      IconButton(
                          onPressed: () {
                            controller.clickSearchClue();
                          },
                          icon: Icon(O2IconFont.ooiconFont('ooicon-search')))
                    ],
                  )),
              Expanded(child: clueListView(context))
            ],
          ));
    });
  }

  Widget _smallScreenView(BuildContext context) {
    return PopScope(
        canPop: false,
        onPopInvokedWithResult: (didPop, result) {
          OLogger.d('============>onPopInvokedWithResult $didPop');
          if (didPop) {
            return;
          }
          OLogger.d('============>onPopInvokedWithResult 2');
        },
        child: Scaffold(
          appBar: AppBar(
            title: Obx(() => Text(
                controller.state.title.isEmpty ? (controller.state.config.value?.appName ?? 'app_name_ai'.tr) : controller.state.title)),
            actions: [
              IconButton(
                  onPressed: () => Get.back(),
                  icon: Icon(O2IconFont.ooiconFont('ooicon-close'), size: 24))
            ],
          ),
          drawer: Drawer(
            child: Column(
              children: [
                Container(
                  height: kToolbarHeight + 28,
                  color: Theme.of(context).colorScheme.primary,
                  alignment: Alignment.centerLeft,
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                ),
                Padding(
                    padding: const EdgeInsets.only(top: 10),
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Expanded(child: newClueButton(context)),
                        IconButton(
                            onPressed: () {
                              Navigator.pop(context);
                              controller.clickSearchClue();
                            },
                            icon: Icon(O2IconFont.ooiconFont('ooicon-search')))
                      ],
                    )),
                Expanded(child: clueListView(context))
              ],
            ),
          ),
          body: SafeArea(
              child: Container(
                  color: Theme.of(context).scaffoldBackgroundColor,
                  child: _buildView(context))),
        ));
  }

  Widget _contentView(BuildContext context) {
    return Obx(() => controller.state.chatInfoList.length > 0
        ? const AIChatMsgListWidget()
        : SingleChildScrollView(
            child: initView(context),
          ));
  }

  /// 底部操作栏
  Widget _bottomBarView(BuildContext context) {
    return Card(
      color: Theme.of(context).colorScheme.surface,
      margin: const EdgeInsets.only(left: 16, right: 16, bottom: 10),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
      child: Column(
        children: [
          _bottomBarAttachmentLine(context),
          const SizedBox(height: 5),
          _bottomBarFirstLine(context),
          const SizedBox(height: 5),
          _bottomBarSecondLine(context),
          const SizedBox(height: 5),
          // _toolView(context),
          // const SizedBox(height: 5)
        ],
      ),
    );
  }

  Widget _bottomBarAttachmentLine(BuildContext context) {
    return Obx(() => controller.state.chatAttachmentList.length > 0
        ? Column(
            children: [
              const SizedBox(height: 5),
              _attachmentListView(context),
            ],
          )
        : Container());
  }

  /// 显示附件区域
  Widget _attachmentListView(BuildContext context) {
    return LayoutBuilder(builder: (context, constraints) {
      final w = constraints.maxWidth;
      const double itemWidth = 48;
      const itemHeight = 48;
      final itemAxisCount = O2Utils.calculateItemsPerRow(w, itemWidth);
      const ratio = itemWidth / itemHeight;
      return Obx(() => GridView.count(
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          crossAxisCount: itemAxisCount,
          mainAxisSpacing: 10,
          crossAxisSpacing: 5,
          childAspectRatio: ratio,
          children: controller.state.chatAttachmentList.values.map((element) {
            return InkWell(
                onTap: () => controller.clickAttachmentItem(element),
                child: _attachmentItemView(context, element));
          }).toList()));
    });
  }

  Widget _attachmentItemView(BuildContext context, AIFileUploadItem item) {
    Image imageView;
    Map<String, String> headers = {};
    headers[O2ApiManager.instance.tokenName] =
        O2ApiManager.instance.o2User?.token ?? '';
    Align loadingOrDelete;
    if (item.fileLocalPath?.isImageFileName == true) {
      imageView = Image(
          image: FileImage(File(item.fileLocalPath!)),
          height: 48,
          fit: BoxFit.fill);
    } else {
      String icon = FileIcon.getFileIconAssetsNameByExtension(item.ext ?? '');
      imageView = Image.asset(
        'assets/images/$icon',
        height: 48,
        width: 48,
        excludeFromSemantics: true,
        gaplessPlayback: true,
      );
    }
    // 已经上传完成
    if (item.fileId != null && item.fileId!.isNotEmpty) {
      loadingOrDelete = const Align(
          alignment: Alignment.topRight,
          child: Padding(
              padding: EdgeInsets.all(5),
              child:
                  Icon(Icons.do_not_disturb_on, color: Colors.red, size: 24)));
    } else {
      loadingOrDelete = const Align(
        alignment: Alignment.center,
        child: CircularProgressIndicator(),
      );
    }
    return Stack(children: [
      Align(alignment: Alignment.center, child: imageView),
      loadingOrDelete
    ]);
  }

  Widget _bottomBarFirstLine(BuildContext context) {
    return Obx(() => Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const SizedBox(width: 8),
            if (controller.state.speechEnabled)
              _iconBtn(
                  controller.state.inputTypeVoice
                      ? O2IconFont.ooiconFont('ooicon-keyboard')
                      : O2IconFont.ooiconFont('ooicon-voice'),
                  () => controller.clickVoiceBtn()),
            // if (!controller.state.speechEnabled) _notInstallVoiceBtn(context),
            Expanded(
              flex: 1,
              child: Padding(
                padding: const EdgeInsets.only(left: 5, right: 5),
                child: controller.state.inputTypeVoice
                    ? controller.state.aiResponsing
                        ? _disableVoiceBtn(context)
                        : SpeechButton(
                            onTapDown: (x) => controller.startRecorder(),
                            onTapUp: (x) => controller.stopRecorder(),
                            onTapCancel: () => controller.stopRecorder(),
                          )
                    : _inputView(context),
              ),
            ),
            const SizedBox(width: 8),
          ],
        ));
  }

  // Widget _notInstallVoiceBtn(BuildContext context) {
  //   return Obx(() {
  //     final status = controller.state.speechStatus.value;
  //     Widget top = Container();
  //     if (status == OnnxModelStatus.notInstall) {
  //       top = Align(
  //           alignment: Alignment.topRight,
  //           child: Padding(
  //             padding: const EdgeInsets.all(5),
  //             child: Icon(O2IconFont.ooiconFont('ooicon-down'),
  //                 size: 16, color: Colors.red),
  //           ));
  //     } else if (status == OnnxModelStatus.installing) {
  //       top = const Align(
  //         alignment: Alignment.center,
  //         child: CircularProgressIndicator(),
  //       );
  //     } else if (status == OnnxModelStatus.fail) {
  //       top = Align(
  //         alignment: Alignment.bottomRight,
  //         child: Icon(O2IconFont.ooiconFont('ooicon-remove_outline'),
  //             size: 16, color: AppColor.hintText),
  //       );
  //     }

  //     return GestureDetector(
  //         onTap: () => controller.clickCheckOnnx(),
  //         child: SizedBox(
  //             width: 48,
  //             height: 48,
  //             child: Stack(
  //               children: [
  //                 Align(
  //                     alignment: Alignment.center,
  //                     child: Padding(
  //                         padding: const EdgeInsets.all(10),
  //                         child: Icon(O2IconFont.ooiconFont('ooicon-voice'),
  //                             size: 24))),
  //                 top
  //               ],
  //             )));
  //   });
  // }

  Widget _disableVoiceBtn(BuildContext context) {
    return Container(
        height: 48,
        decoration: BoxDecoration(
            color: Theme.of(context).scaffoldBackgroundColor,
            border: Border.all(color: Theme.of(context).dividerColor),
            borderRadius: BorderRadius.circular(4)),
        child: Center(
            child: Text('ai_chat_start_loading'.tr,
                style: const TextStyle(color: AppColor.hintText))));
  }

  Widget _bottomBarSecondLine(BuildContext context) {
    return Row(
      children: [
        const SizedBox(width: 8),
        // ai 模式
        generateTypeChooseView(context),
        const Spacer(),
        _iconBtn(O2IconFont.ooiconFont('ooicon-create'),
            () => controller.clickAddAttachment()), // 图片附件等工具
        // 发送消息按钮
        Obx(() => IconButton(
              onPressed: () => controller.clickSendMsg(),
              icon: Container(
                decoration: BoxDecoration(
                  color: controller.state.aiResponsing
                      ? Theme.of(context).scaffoldBackgroundColor
                      : Theme.of(context).colorScheme.primary, // 背景色
                  shape: BoxShape.circle, // 圆形
                ),
                padding: const EdgeInsets.all(8.0), // 内边距控制大小
                child: Center(
                    child: Icon(O2IconFont.ooiconFont('ooicon-send'),
                        color: Colors.white, size: 16)),
              ),
              iconSize: 40.0, // 图标大小（容器内 icon 大小）
              padding: EdgeInsets.zero, // 清除默认内边距
              constraints: const BoxConstraints(),
            )),
        const SizedBox(width: 8),
      ],
    );
  }

  // 文本输入框
  Widget _inputView(BuildContext context) {
    return Column(
      children: [
        const SizedBox(height: 5),
        TextField(
          autofocus: false,
          focusNode: controller.chatInputNode,
          // contextMenuBuilder: (context, editableTextState) {
          //   return _buildInputViewContextMenu(context, editableTextState);
          // },
          controller: controller.chatInputController,
          scrollController: controller.chatInputScrollController,
          decoration: InputDecoration(
              isDense: true,
              hintText: 'ai_input_hint'.tr,
              hintStyle: Theme.of(context).textTheme.bodySmall,
              filled: true,
              fillColor: Theme.of(context).colorScheme.surface,
              border: InputBorder.none,
              enabledBorder: InputBorder.none,
              disabledBorder: InputBorder.none,
              errorBorder: InputBorder.none,
              focusedErrorBorder: InputBorder.none,
              focusedBorder: InputBorder.none),
          style: Theme.of(context).textTheme.bodyLarge,
          // keyboardType: TextInputType.multiline,
          maxLines: 5,
          minLines: 1,
          textInputAction: TextInputAction.newline,
          // onEditingComplete: ()=>controller.onSendText(),
          // onSubmitted: (value) => controller.onSendText(),
        ),
        const SizedBox(height: 5),
      ],
    );
  }

  Widget generateTypeChooseView(BuildContext context) {
    return Obx(() => controller.state.generateType.value != null &&
            controller.state.config.value?.o2AiEnable == true
        ? InkWell(
            onTap: () => controller.clickChooseGenerateType(),
            child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
              decoration: BoxDecoration(
                border: Border.all(color: Colors.grey.shade300),
                borderRadius: BorderRadius.circular(24),
              ),
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Icon(
                      O2IconFont.ooiconFont(
                          controller.state.generateType.value?.iconClass ?? ''),
                      size: 20,
                      color: Theme.of(context).textTheme.bodyMedium?.color),
                  const SizedBox(width: 6),
                  Text(
                    controller.state.generateType.value?.name ?? '',
                    style: Theme.of(context).textTheme.bodyMedium,
                  ),
                  const SizedBox(width: 6),
                  Icon(Icons.arrow_drop_down,
                      size: 20,
                      color: Theme.of(context).textTheme.bodyMedium?.color),
                ],
              ),
            ))
        : Container());
  }

  /// 按钮
  Widget _iconBtn(IconData icon, GestureTapCallback tap) {
    return IconButton(onPressed: tap, icon: Icon(icon, size: 24));
  }

  Widget initView(BuildContext context) {
    return Obx(() {
      List<Widget> list = [];
      if (controller.state.config.value?.appIconUrl?.isNotEmpty == true) {
        String url =
            '${O2ApiManager.instance.webBaseUrl()}/${controller.state.config.value!.appIconUrl}';
        list.add(networkImageView(url));
      }
      if (controller.state.config.value?.title?.isNotEmpty == true) {
        list.add(Padding(
            padding: const EdgeInsets.only(top: 10),
            child: Text(controller.state.config.value!.title!,
                style: Theme.of(context).textTheme.titleMedium)));
      }
      if (controller.state.config.value?.desc?.isNotEmpty == true) {
        list.add(Padding(
            padding: const EdgeInsets.only(top: 10),
            child: Text(controller.state.config.value!.desc!,
                style: Theme.of(context).textTheme.bodySmall)));
      }
      return Center(
          child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(mainAxisSize: MainAxisSize.min, children: list),
      ));
    });
  }

  Widget networkImageView(String url) {
    Map<String, String> headers = {};
    headers[O2ApiManager.instance.tokenName] =
        O2ApiManager.instance.o2User?.token ?? '';
    return CachedNetworkImage(
      imageUrl: url,
      httpHeaders: headers,
      width: 96,
      height: 96,
      fit: BoxFit.fill,
    );
  }

  Widget newClueButton(BuildContext context) {
    return Padding(
        padding: const EdgeInsets.only(left: 16, right: 10),
        child: SizedBox(
            width: double.infinity,
            height: 40,
            child: O2ElevatedButton(() {
              // 点击
              controller.clickNewClue();
              if (!controller.state.isBigScreen) {
                  Navigator.pop(context);
                }
            },
                Text(
                  'ai_new_clue'.tr,
                ))));
  }

  Widget clueListView(BuildContext context) {
    return Obx(() {
      final list = controller.state.clueList.toList();
      final currentId = controller.state.currentClue.value?.id;
      return GroupedListView<AIClueInfo, String>(
          elements: list,
          groupBy: (element) => '${element.groupOrder ?? 0}',
          groupHeaderBuilder: (element) {
            return Container(
                color: Theme.of(context).scaffoldBackgroundColor,
                child: Padding(
                    padding:
                        const EdgeInsets.only(left: 8, top: 10, bottom: 10),
                    child: Text(element.groupTag ?? '')));
          },
          order: GroupedListOrder.DESC,
          itemComparator: (a, b) {
            if (a.createDateTime == null || b.createDateTime == null) {
              return 0;
            }
            final dateA = DateTime.parse(a.createDateTime!);
            final dateB = DateTime.parse(b.createDateTime!);
            return dateA.compareTo(dateB);
          },
          itemBuilder: (context, element) {
            var title = element.title;
            if (title == null || title.isEmpty == true) {
              title = 'ai_unknow_title'.tr;
            }
            return ListTile(
              onTap: () {
                if (!controller.state.isBigScreen) {
                  Navigator.pop(context);
                }
                controller.clickLoadClue(element);
              },
              selected: currentId == element.id,
              title: Text(title),
            );
          });
    });
  }
}
